package com.rules.admin.domain;


import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;

import com.gillion.grule.client.utils.ContextHolder;
import com.google.common.base.Splitter;
import java.util.Iterator;
import java.util.List;

import com.rules.admin.utils.JsonMapperHolder;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.expression.EvaluationException;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.ParseException;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.stereotype.Component;

@Component

public class UserInfoAttributesConverter {
    private static final Logger logger = LoggerFactory.getLogger(UserInfoAttributesConverter.class);
    private String userInfoCollectorName;
    private List<AttrMap> attrMaps;

    public UserInfoAttributesConverter() {
    }

    public final ObjectNode getUserInfoAttributes() {
        UserInfoCollector userInfoCollector = (UserInfoCollector)ContextHolder.getBean(this.userInfoCollectorName);
        ObjectNode userInfoAttributes = JsonMapperHolder.createObjectNode();
        IUser user = userInfoCollector != null ? userInfoCollector.getCurrentLoginUser() : null;
        Iterator var4 = this.attrMaps.iterator();

        while(var4.hasNext()) {
            AttrMap attrMap = (AttrMap)var4.next();
            attrMap.read(user).writeTo(userInfoAttributes);
        }

        return userInfoAttributes;
    }

    public String getUserInfoCollectorName() {
        return this.userInfoCollectorName;
    }

    public void setUserInfoCollectorName(String userInfoCollectorName) {
        this.userInfoCollectorName = userInfoCollectorName;
    }

    public void setAttrMaps(List<AttrMap> attrMaps) {
        this.attrMaps = attrMaps;
    }

    public static final class AttrMap {
        private final String readProp;
        private final String writeProp;

        public AttrMap(String readProp, String writeProp) {
            this.readProp = readProp;
            this.writeProp = writeProp;
        }

        public AttrWriter read(IUser user) {
            if (StringUtils.isNotBlank(this.readProp) && user != null) {
                ExpressionParser expressionParser = new SpelExpressionParser();

                Object value;
                try {
                    value = expressionParser.parseExpression(this.readProp).getValue(user);
                } catch (EvaluationException var5) {
                    EvaluationException e = var5;
                    UserInfoAttributesConverter.logger.error("根据表达式获取用户属性值失败", this.readProp, e);
                    value = null;
                } catch (ParseException var6) {
                    ParseException e = var6;
                    UserInfoAttributesConverter.logger.error("根据表达式获取用户属性值失败", this.readProp, e);
                    value = null;
                }

                return new AttrWriter(value);
            } else {
                return new AttrWriter((Object)null);
            }
        }

        final class AttrWriter {
            public final Object value;

            public AttrWriter(Object value) {
                this.value = value;
            }

            public final void writeTo(ObjectNode desc) {
                if (StringUtils.isNotBlank(AttrMap.this.writeProp) && this.value != null) {
                    Iterator<String> props = Splitter.on('.').split(AttrMap.this.writeProp).iterator();
                    this.write(props, desc);
                }

            }

            private void write(Iterator<String> props, ObjectNode desc) {
                String propName = (String)props.next();
                ObjectNode objectNode;
                if (props.hasNext()) {
                    objectNode = desc.with(propName);
                    this.write(props, objectNode);
                } else if (desc.has(propName)) {
                    objectNode = (ObjectNode)JsonMapperHolder.convert(this.value, ObjectNode.class);
                    desc.with(propName).setAll(objectNode);
                } else {
                    desc.set(propName, (JsonNode)JsonMapperHolder.convert(this.value, JsonNode.class));
                }

            }
        }
    }
}

